package main

/*
bufio.Reader类型值中的缓冲区起着怎样的作用？
	1.bufio.Reader类型的值（以下简称Reader值）内的缓冲区，其实就是一个数据存储中介，它介于底层读取器与读取方法及其调用方之间。
所谓的底层读取器，就是在初始化此类值的时候传入的io.Reader类型的参数值。
	2.Reader值的读取方法一般都会先从其所属值的缓冲区中读取数据。同时，在必要的时候，它们还会预先从底层读取器那里读出一部分数据，并暂存于缓冲区之中以备后用。
	缓冲区的好处:
		可以在大多数的时候降低读取方法的执行时间。虽然，读取方法有时还要负责填充缓冲区，但从总体来看，读取方法的平均执行时间一般都会因此有大幅度的缩短。

bufio.Reader类型并不是开箱即用的，因为它包含了一些需要显式初始化的字段。
	1.buf：[]byte类型的字段，即字节切片，代表缓冲区。虽然它是切片类型的，但是其长度却会在初始化的时候指定，并在之后保持不变。
	2.rd：io.Reader类型的字段，代表底层读取器。缓冲区中的数据就是从这里拷贝来的。
	3.r：int类型的字段，代表对缓冲区进行下一次读取时的开始索引。我们可以称它为已读计数。
	4.w：int类型的字段，代表对缓冲区进行下一次写入时的开始索引。我们可以称之为已写计数。
	5.err：error类型的字段。它的值用于表示在从底层读取器获得数据时发生的错误。这里的值在被读取或忽略之后，该字段会被置为nil。
	6.lastByte：int类型的字段，用于记录缓冲区中最后一个被读取的字节。读回退时会用到它的值。
	7.lastRuneSize：int类型的字段，用于记录缓冲区中最后一个被读取的 Unicode 字符所占用的字节数。读回退的时候会用到它的值。这个字段只会在其所属值的ReadRune方法中才会被赋予有意义的值。在其他情况下，它都会被置为-1。

bufio包为我们提供了两个用于初始化Reader值的函数
	NewReader；
	NewReaderSize；
	它们都会返回一个*bufio.Reader类型的值。
	NewReader函数初始化的Reader值会拥有一个默认尺寸的缓冲区。这个默认尺寸是 4096 个字节，即：4 KB。而NewReaderSize函数则将缓冲区尺寸的决定权抛给了使用方。

问题 1：bufio.Writer类型值中缓冲的数据什么时候会被写到它的底层写入器？

	bufio.Writer类型都有哪些字段?
		1.err：error类型的字段。它的值用于表示在向底层写入器写数据时发生的错误。
		2.buf：[]byte类型的字段，代表缓冲区。在初始化之后，它的长度会保持不变。
		3.n：int类型的字段，代表对缓冲区进行下一次写入时的开始索引。我们可以称之为已写计数。
		4.wr：io.Writer类型的字段，代表底层写入器。

	bufio.Writer类型有一个名为Flush的方法，它的主要功能是把相应缓冲区中暂存的所有数据，都写到底层写入器中。数据一旦被写进底层写入器，该方法就会把它们从缓冲区中删除掉。

	在通常情况下，只要缓冲区中的可写空间无法容纳需要写入的新数据，Flush方法就一定会被调用。并且，bufio.Writer类型的一些方法有时候还会试图走捷径，跨过缓冲区而直接对接数据供需的双方。

	使用bufio.Writer最佳实践？
		在把所有的数据都写入Writer值之后，再调用一下它的Flush方法，显然是最稳妥的。

问题 ：bufio.Reader类型读取方法有哪些不同？
	bufio.Reader类型拥有很多用于读取数据的指针方法，这里面有 4 个方法可以作为不同读取流程的代表，它们是：Peek、Read、ReadSlice和ReadBytes。

    Peek方法:
		Reader值的Peek方法的功能是：读取并返回其缓冲区中的n个未读字节，并且它会从已读计数代表的索引位置开始读。
			1.在缓冲区未被填满，并且其中的未读字节的数量小于n的时候，该方法就会调用fill方法，以启动缓冲区填充流程。
			2.如果调用方给定的n比缓冲区的长度还要大，或者缓冲区中未读字节的数量小于n，那么Peek方法就会把“所有未读字节组成的序列”作为第一个结果值返回。
		同时，它通常还把“bufio.ErrBufferFull变量的值（以下简称缓冲区已满的错误）”作为第二个结果值返回，用来表示：虽然缓冲区被压缩和填满了，但是仍然满足不了要求。
			3.只有在上述的情况都没有出现时，Peek方法才能返回：“以已读计数为起始的n个字节”和“表示未发生任何错误的nil”。

		bufio.Reader类型的 Peek 方法有一个鲜明的特点，那就是：即使它读取了缓冲区中的数据，也不会更改已读计数的值。

	ReadSlice方法:
		1.ReadSlice方法会先在其缓冲区的未读部分中寻找分隔符。如果未能找到，并且缓冲区未满，那么该方法会先通过调用fill方法对缓冲区进行填充，然后再次寻找，如此往复。
		2.如果在填充的过程中发生了错误，那么它会把缓冲区中的未读部分作为结果返回，同时返回相应的错误值。
		3.注意，在这个过程中有可能会出现虽然缓冲区已被填满，但仍然没能找到分隔符的情况。
		4.这时，ReadSlice方法会把整个缓冲区（也就是buf字段代表的字节切片）作为第一个结果值，并把缓冲区已满的错误（即bufio.ErrBufferFull变量的值）作为第二个结果值。
		5.一旦ReadSlice方法找到了分隔符，它就会在缓冲区上切出相应的、包含分隔符的字节切片，并把该切片作为结果值返回。无论分隔符找到与否，该方法都会正确地设置已读计数的值。

	ReadBytes方法:
		ReadBytes方法会通过调用ReadSlice方法一次又一次地从缓冲区中读取数据，直至找到分隔符为止。
		1.在这个过程中，ReadSlice方法可能会因缓冲区已满而返回所有已读到的字节和相应的错误值，但ReadBytes方法总是会忽略掉这样的错误，并再次调用ReadSlice方法，这使得后者会继续填充缓冲区并在其中寻找分隔符。
		2.除非ReadSlice方法返回的错误值并不代表缓冲区已满的错误，或者它找到了分隔符，否则这一过程永远不会结束。
		3.如果寻找的过程结束了，不管是不是因为找到了分隔符，ReadBytes方法都会把在这个过程中读到的所有字节，按照读取的先后顺序组装成一个字节切片，并把它作为第一个结果值。
	如果过程结束是因为出现错误，那么它还会把拿到的错误值作为第二个结果值。


*/

func main() {



}
